package aiproject3.models;

public class DiscreteGaussianDistribution {

    // The mean of the distribution.
    private double mean;
    
    // The standard deviation of the distribution.
    private double stdDev;
    
    // The number of samples taken.
    private int numSamples = 0;

    /**
     * Constructs a Gaussian distribution with the given mean and standard
     * deviation.
     * 
     * @param mean The mean of the distribution.
     * @param stdDev The standard deviation of the distribution.
     */
    public DiscreteGaussianDistribution(double mean, double stdDev) {
        this.mean = mean;
        this.stdDev = stdDev;
    }
    
    /**
     * Constructs a Gaussian distribution with a mean of 0 and a standard deviation
     * of 1.
     */
    public DiscreteGaussianDistribution() {
        this.mean = 0;
        this.stdDev = 1.0f;
    }
    
    /**
     * Returns the probability of some value x on this distribution.
     * 
     * @param x The value to be checked against.
     * @return
     */
    public double pdf(int x) {
        
        double power = x-mean;
        power = -(power*power)/(2*stdDev*stdDev);
        
        double prob = 1/Math.sqrt(2*Math.PI*(stdDev*stdDev));
        prob = prob * Math.exp(power);
        
        return prob;
    }
    
    public void addSample(int x) {
        
        numSamples++;
        
        // Re-scale the mean.
        mean = mean * (numSamples-1)/numSamples;
        mean += ((double)x)/numSamples;
        
        // Re-scale the standard deviation.
        stdDev = stdDev*stdDev * (numSamples-1)/numSamples;
        stdDev += Math.pow(((double)x - mean)/(20*numSamples),2);
        stdDev = Math.sqrt(stdDev);
        
        System.out.println("Updated distribution: m=" + mean + ", s=" + stdDev);
    }

}
